package com.ibm.cloud.banking.trans.account;

import com.ibm.cloud.banking.facade.account.IAccountFacade;
import com.ibm.cloud.banking.facade.account.dto.AccountBalanceUpdateDTO;
import com.ibm.cloud.banking.facade.account.dto.AccountInfoDTO;
import com.ibm.cloud.banking.facade.media.IMediaCardFacade;
import com.ibm.cloud.banking.facade.media.dto.MediaCardDTO;
import com.ibm.cloud.banking.trans.account.dto.Resp211228;
import org.apache.camel.Exchange;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.spi.Synchronization;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class Trans211228 extends RouteBuilder {

    @Resource
    IAccountFacade accountFacade;

    @Resource
    IMediaCardFacade mediaCardFacade;

    String PCS_CODE = "T23";
    String ROUTE_URI = "direct:T23";
    String ROUTE_DESC = "账户存款交易";
    String ROUTE_ID = "PCS-FLOW-T23";

    String GETTING_MEDIA_CARD_INFO = "direct:511";
    String GETTING_ACCOUNT_INFO = "direct:512";
    String UPDATE_ACCOUNT_BALANCE = "direct:513";
    String GETTING_ACCOUNT_BALANCE = "direct:514";

    private final static String SUCCESS_CODE = "0000";
    private final static String SUCCESS_MSG = "交易成功";

    private final static String SEND_MSG_TEMPLATE = "卡号[%s]存入金额[%s]，账户可用余额[%s]";


    @Override
    public void configure() throws Exception {

        from(ROUTE_URI)
                .routeDescription(ROUTE_DESC)
                .routeId(ROUTE_ID)
                .log("开始执行账户存款交易。")
                .to(GETTING_MEDIA_CARD_INFO)
                .to(GETTING_ACCOUNT_INFO)
                .to(UPDATE_ACCOUNT_BALANCE)
                .log("账户存款交易执行结束。");


        // 检查介质真伪，检查卡状态是否正常
        from(GETTING_MEDIA_CARD_INFO)
                .process(exchange -> {
                    Map<String, Object> requestMsg = (LinkedHashMap<String, Object>)exchange.getIn().getBody();
                    String cardNo = (String)requestMsg.get("cardNo");
                    String custName = (String)requestMsg.get("accountName");
                    BigDecimal amount = new BigDecimal((String)requestMsg.get("amount"));
                    Integer sequence = Integer.valueOf((String)requestMsg.get("sequence"));
                    exchange.setProperty("card_no",cardNo);
                    exchange.setProperty("cust_name",custName);
                    exchange.setProperty("trans_amount",amount);
                    exchange.setProperty("trans_sequence",sequence);
                    exchange.getIn().setBody(cardNo, String.class);
                })
                .bean(mediaCardFacade, "checkMediaCardStatus").log("卡信息验证");

        // 检查活期结算账号状态，账户名称是否一致
        from(GETTING_ACCOUNT_INFO)
                .process(exchange -> {
                    MediaCardDTO mediaCardDTO = exchange.getIn().getBody(MediaCardDTO.class);
                    exchange.setProperty("account_no",mediaCardDTO.getAccountNo());
                    AccountInfoDTO accountInfoDTO = new AccountInfoDTO();
                    accountInfoDTO.setAccountNo(mediaCardDTO.getAccountNo());
                    accountInfoDTO.setCustomerName((String) exchange.getProperty("cust_name"));
                    exchange.getIn().setBody(accountInfoDTO, AccountInfoDTO.class);
                })
                .bean(accountFacade, "checkAcctDepositStatus").log("检查活期结算账号状态、账户名称");

        // 账户余额更新，登记交易明细
        from(UPDATE_ACCOUNT_BALANCE)
                .process(exchange -> {
                    AccountInfoDTO accountInfoDTO = exchange.getIn().getBody(AccountInfoDTO.class);
                    AccountBalanceUpdateDTO balanceUpdateDTO = new AccountBalanceUpdateDTO();
                    balanceUpdateDTO.setTransAmount((BigDecimal) exchange.getProperty("trans_amount"));
                    balanceUpdateDTO.setDeposit(true);
                    balanceUpdateDTO.setAccountNo(accountInfoDTO.getAccountNo());
                    balanceUpdateDTO.setTransCode(PCS_CODE);
                    exchange.getIn().setBody(balanceUpdateDTO, AccountBalanceUpdateDTO.class);
                    exchange.getUnitOfWork().addSynchronization(new Synchronization() {
                        @Override
                        public void onComplete(Exchange exchange) {

                        }

                        @Override
                        public void onFailure(Exchange exchange) {
                            accountFacade.updateAccountBalanceForRefund(balanceUpdateDTO, true);
                        }
                    });
                })
                .bean(accountFacade, "updateAccountBalance")
                .process(exchange -> {
                    String transNo = exchange.getIn().getBody(String.class);
                    Resp211228 response = new Resp211228();
                    response.setCode(SUCCESS_CODE);
                    response.setMessage(SUCCESS_MSG);
                    response.setTransNo(transNo);
                    response.setTransTime(LocalDateTime.now().toString());
                    response.setSequence((Integer)exchange.getProperty("trans_sequence"));
                    exchange.getIn().setBody(response, Resp211228.class);
                })
                .log("账户余额更新，登记交易明细");

    }
}
